package com.binc.testspring.controller;

import com.binc.testspring.dto.Result;
import com.binc.testspring.service.HttpAPIService;
import com.binc.testspring.service.ICustomerService;
import com.binc.testspring.service.RetrofitAPIService;
import com.binc.testspring.service.RetrofitApi2;
import com.binc.testspring.vo.IdVo;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 这是测试retrofit   并且是验证传与第三方接口传输文件
 */
@Api(tags = "retrofit框架")
@Slf4j
@RestController
@RequestMapping("/test/retrofit")
public class RetrofitController {
    final static String url= "http://localhost:5555/erp.transaction.api/third/"; //这个是本地项目的一个接口u，假装是第三方的接口了；先启动这个项目；然后单独跑测试；

    @Resource
    private HttpAPIService httpAPIService;

    private static  OkHttpClient mClient= null;  //这个的初始话用的是 static  如果想用别的方式的话，可以让当前bean 实现 InitializingBean 接口 并重写 afterPropertiesSet()方法  （语雀上有这个代码 https://www.yuque.com/binc/java/gt9fvh）
  /**
     * 创建链接
     * @return
     */
    private Retrofit getRetrofit() {
        return new Retrofit.Builder()
                // 设置OKHttpClient,如果不设置会提供一个默认的
                .client(new OkHttpClient())
                //设置baseUrl
                .baseUrl(url)
                //添加Gson转换器
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    private Retrofit getRetrofit2() {
        return new Retrofit.Builder()
                // 设置OKHttpClient,如果不设置会提供一个默认的
                .client(new OkHttpClient())
                //设置baseUrl
                .baseUrl("http://localhost:5555/erp.transaction.api/")
                //添加Gson转换器
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }



    static {
        // 用这种方式自己扩展okhttpclient
        mClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        try {
                            Request.Builder builder = chain.request().newBuilder();
                            builder.addHeader("Accept-Charset", "UTF-8");
                            builder.addHeader("Accept", " application/json");
                            builder.addHeader("Content-type", "application/json");
                            Request request = builder.build();
                            return chain.proceed(request);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                }).build();

    }


    /**
     * Retrofit使用OkHttpClient来实现网络请求，
     * <p>  这个OkHttpClient虽然不能替换为其他的网络执行框架比如Volley，
     * <p>  但是Retrofit允许我们使用自己扩展OkHttpClient，一般最常扩展的就是Interceptor拦截器了
     *
     * @return
     */
    private Retrofit getRetrofit_3(String url) {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                /**
                 *  addConverterFactory 扩展的是对返回的数据类型的自动转换，把一种数据对象转换为另一种数据对象。
                 *  在具体场景中，GsonConverterFactory可以把Http访问得到的json字符串转换为Java数据对象 **Entity、**Dto，这个数据对象是在retrofit接口中要求的（RetrofitAPIService。java）。
                 * 这种转换我们自己也经常做，很好理解。
                 * 如果现有的扩展包不能满足需要，可以继承Retrofit的接口。retrofit2.Converter<F,T>，自己实现Converter和ConverterFactory。
                 * 在创建Retrofit对象时，可以插入我们自定义的ConverterFactory。
                 *
                 */
                .client(mClient)
                .build();

        return retrofit;
    }




    /**
     * 第一个post  同步    对象接受返回结果   用例
     * @return
     * @throws Exception
     */
    @RequestMapping("/test1")
    public String test1() throws Exception {
        Retrofit retrofit = getRetrofit();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        IdVo idVo = new IdVo();
        idVo.setId(123L);
        idVo.setType(1);
        // 5. 执行请求
        Call<Result<List<String>>> call = retrofitAPIService.binc2(idVo);
        Response<Result<List<String>>> response = call.execute();

        // 6. 判断是否成功，成功则打印出数据
        if (response.isSuccessful()) {
            Result<List<String>> body = response.body();
            System.out.println(body);
        }

        return null;
    }




    /**
     * 测试返回结果用jsonobjec接受
     *
     * 追加 @headers  或者 @header  注解的使用
     * @return
     * @throws Exception
     */
    @RequestMapping("/test2")
    public String test2() throws Exception {
        Retrofit retrofit = getRetrofit();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        IdVo idVo = new IdVo();
        idVo.setId(123L);
        idVo.setType(1);
        // 5. 执行请求
        Call<JsonObject> call = retrofitAPIService.binc3(idVo);
        Response<JsonObject> response = call.execute();

        // 6. 判断是否成功，成功则打印出数据
        if (response.isSuccessful()) {
            JsonObject body = response.body();
            JsonElement code = body.get("code");
            System.out.println(code);  //
            System.out.println(body);
        }

        System.out.println("-------------------------------");
        // 5. 执行请求
        String authorization = "eyJhbGciOiJSUzI1NiJ9.eyJkdCI6InBjX3dlYiIsInR0IjoiMSIsInN1YiI6IjU3MjYyNTY0MTIzNTI1MTIwMCIsIlVOb25jZSI6ImMwNTFiMGY4LTJiZmItNDMyZS1hOGE0LWFkOGFjNTBiMmJhMiIsInJvbGUiOiI1ODUwMTQ2NDI3MTc5ODI3MjAiLCJpc3MiOiJ5anpmLmNvbSIsImV4cCI6MTYzMDY1NjEwOSwiaWF0IjoxNjMwNDgzMzA5LCJqdGkiOiIyNjFlYjFmZS1jMmM4LTQ4MjctODA2ZC1kZWU3NTVkMTQ3MGQifQ.Cw3qa-nDR9odlcFFoKMKm_fJ4fuY-8xOI70eet0TTj-_UH90W5EvmHG1ZIKnItosgPmJAp9-f_fg4aBNsoZ8GVinpSn3kIGwMSaSqs3z88BDg6eTYDKrfTCAMJlVwB0Brqpqs88PZ6-NCcVDODm4jwYCtz6PEjtqa3fLvimr68w";
        String citycode = "450100";
        String orgid = "552692373611008128";

         call = retrofitAPIService.binc4(authorization,citycode,orgid,idVo);
         response = call.execute();

        // 6. 判断是否成功，成功则打印出数据
        if (response.isSuccessful()) {
            JsonObject body = response.body();
            JsonElement code = body.get("code");
            System.out.println(code);  //
            System.out.println(body);
        }

        return null;
    }

    /**
     * test1  test2  执行的是同步请求
     * test3  实验一下异步请求
     * @return
     * @throws Exception
     */
    @RequestMapping("/test3")
    public String test3() throws Exception {
        Retrofit retrofit = getRetrofit();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        IdVo idVo = new IdVo();
        idVo.setId(123L);
        idVo.setType(1);
        // 5. 执行请求
        Call<Result<List<String>>> call = retrofitAPIService.binc2(idVo);
        call.enqueue(new Callback<Result<List<String>>>() {
            /*
             * 正常回调
             */
            @Override
            public void onResponse(Call<Result<List<String>>> call, Response<Result<List<String>>> response) {
                Result<List<String>> body = response.body();
                System.out.println(body);
            }

            /*
            失败回调
             */
            @Override
            public void onFailure(Call<Result<List<String>>> call, Throwable throwable) {
                System.out.println(throwable.getMessage());
            }
        });

        //一步的时候这里会优先跑完，如果需要等待结果的话，就在这个位置停顿一下；
        System.out.println(123);
        return null;
    }


    /**
     * post请求
     * 测试  http    url  注解
     * @return
     * @throws Exception
     */
    @RequestMapping("/test4")
    public String test4() throws Exception {
        Retrofit retrofit = getRetrofit();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        IdVo idVo = new IdVo();
        idVo.setId(123L);
        idVo.setType(1);
        // 5. 执行请求
        Call<JsonObject> call = retrofitAPIService.http_annotation(idVo);   //测试 http注解    访问的是baseUrl+path（post）
        Response<JsonObject> response = call.execute();

        // 6. 判断是否成功，成功则打印出数据
        if (response.isSuccessful()) {
            JsonObject body = response.body();
            JsonElement code = body.get("code");
            System.out.println(code);  //
            System.out.println(body);
        }

        System.out.println("-------------------------------");
        String uri = url+"other/binc1";
        Call<JsonObject> cc = retrofitAPIService.url_annotation(uri,idVo);   //测试 url注解    访问的是 不在使用baseurl   改为用单独url +path
        Response<JsonObject> ss = cc.execute();

        // 6. 判断是否成功，成功则打印出数据
        if (ss.isSuccessful()) {
            JsonObject body = ss.body();
            JsonElement code = body.get("code");
            System.out.println(code);  //
            System.out.println(body);
        }

        return null;
    }

    /**
     * post请求
     * @Streaming:用于下载大文件  这个写了测试代码，但是没有真正的服务端支持
     * @return
     * @throws Exception
     */
    @RequestMapping("/test5")
    public String test5() throws Exception {
        Retrofit retrofit = getRetrofit();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        IdVo idVo = new IdVo();
        idVo.setId(123L);
        idVo.setType(1);

        System.out.println("-------------------------------");
        String uri = url+"other/binc1";
        //@Streaming:用于下载大文件  这个写了测试代码，但是没有真正的服务端支持
        Call<ResponseBody> responseBodyCall = retrofitAPIService.downloadFileWithDynamicUrlAsync(uri);//测试 url注解    访问的是 不在使用baseurl   改为用单独url +path
        Response<ResponseBody> response = responseBodyCall.execute();
        ResponseBody body = response.body();
        long fileSize = body.contentLength();
        InputStream inputStream = body.byteStream();

        return null;
    }
/********************************************************************************************************/
/********************************************************************************************************/
/********************************************************************************************************/
/********************************************************************************************************/
//这里隔开，上边是自己创建的retrofit链接
    //下边开始用retrofit starter的创建的链接
/********************************************************************************************************/
/********************************************************************************************************/
/********************************************************************************************************/
/********************************************************************************************************/
/********************************************************************************************************/

    @Autowired
    ICustomerService customerServiceImpl;

    @Autowired
    RetrofitApi2 retrofitApi2;

    /**
     * 不在自己创建链接了，用retrofit starter创建链接
     * @return
     */
    @PostMapping("/RetrofitClient_test")
    public Result<String> retrofitClient_test() throws IOException {
        log.info("测试@restrofitClient注解,retrofitClient_test 开始; ");
        //JsonObject jsonObject = customerServiceImpl.retrofitClientTest();
        Call<JsonObject> jsonObjectCall = retrofitApi2.binc4();
        Response<JsonObject> execute = jsonObjectCall.execute();
        execute.body();


        Retrofit retrofit = getRetrofit2();
        // 4. 执行retrofit.create方法
        RetrofitAPIService retrofitAPIService = retrofit.create(RetrofitAPIService.class);

        // 5. 执行请求
        Call<JsonObject> call = retrofitAPIService.binc4();
        Response<JsonObject> response = call.execute();
        JsonObject body = null;
        // 6. 判断是否成功，成功则打印出数据
        if (response.isSuccessful()) {
              body = response.body();
            System.out.println(body);
        }

        Result ok = Result.of("ok");
        ok.setData(body.toString());

        return ok;

    }
    
}
